home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C011.ZIP / TYPESQ.C < prev    next >
Text File  |  1990-01-19  |  6KB  |  272 lines

  1. /********************************************************************
  2.  * C Users Group (U.K) C Source Code Library File CUGLIB.011        *
  3.  * Inquiries to: M. Houston, 36 Whetstone Clo. Farquhar Rd.         *
  4.  * Edgbaston, Birmingham B15 2QN ENGLAND                *
  5.  ********************************************************************
  6.  * File name: typesq.c
  7.  * Program name: typesq
  8.  * Source of file: The Public Domain Software Library.
  9.  * Purpose: types a squeezed file.
  10.  * Changes: <who what when & why major changes have been made>      
  11.  ********************************************************************/
  12.  
  13. /*% cc -O -s % -o type
  14.  
  15. *    TYPE - uses typesq.c for 'sqed' files
  16.   derived from cnode 'cat', typesq, and others. W. Earnest 5/28/82
  17.   Credit to the following and others for parts of the software:
  18.     Dick Greenlaw    (usq)
  19.     Bob Mathias    (typesq)
  20.     Steve Passe    (cnode)
  21.     Joe Shannon    (cnode)
  22.     Chuck Forsberg (Unix version)
  23. */
  24. char Version[] = {"type revised 7-16-82"};
  25.  
  26. #include <stdio.h>
  27. /* #include <signal.h> */
  28. #define ERROR (-1)
  29. #define OK 0
  30. #define PATHLEN 128
  31.  
  32. #define RECOGNIZE 0xFF76    /* unlikely pattern */
  33. #define DLE 0x90        /* repeat byte flag */
  34. #define SPEOF 256        /* special endfile token */
  35. #define NUMVALS 257        /* 256 data values plus SPEOF*/
  36. #define LARGE 30000
  37.  
  38. struct _sqleaf {        /* Decoding tree */
  39.     int _children[2];    /* left, right */
  40. };
  41. struct _sqleaf Dnode[NUMVALS - 1];
  42.  
  43. int early_exit;
  44. FILE *infile;
  45.  
  46. int Bpos;        /* last bit position read */
  47. int Curin;        /* last byte value read */
  48. int Repct;        /* Number of times to retirn value */
  49. int Value;        /* current byte value or EOF */
  50.  
  51. sexit()
  52. {
  53.     early_exit++;
  54. /*    signal(SIGINT, sexit); */
  55. }
  56.  
  57. sequit()
  58. {
  59.     putchar('\n');
  60.     exit(1);
  61. }
  62.  
  63. main(p_argc, p_argv)
  64. int p_argc;
  65. char **p_argv;
  66. {
  67.     char file[PATHLEN];
  68.     register char x;
  69. /*    static char stobuf[BUFSIZ];  */
  70.     extern sexit();
  71.  
  72.  
  73. /*    signal(SIGINT, sexit);     */
  74. /*    signal(SIGQUIT, sequit); */
  75. /*    setbuf(stdout, stobuf);  */
  76.     if (p_argc < 2) {
  77.         fprintf(stderr, "Usage: type name ...\n");
  78.         exit(1);
  79.     }
  80.  
  81.     for (x = 1;x < p_argc;++x) {
  82.         fprintf(stderr, "\n\n======================== Listing %s ========================\n",p_argv[x]);
  83.         switch (catvalid(file, p_argv[x])) {
  84.         case 'q':
  85.             switch (qsend(file)) {
  86.             case ERROR:
  87.                 break;
  88.             case 'a':
  89.                 send_text(file);
  90.             }
  91.             break;
  92.         case 'a':
  93.             send_text(file); break;
  94.         case 'x':
  95.             break;
  96.         }
  97.     }
  98.     return (OK);
  99. }
  100.  
  101. send_text(file)
  102. char *file;
  103. {
  104.     register c;
  105.  
  106.     early_exit = 0;
  107.     while( ((c = getc(infile)) != EOF) && (!early_exit) )
  108.         putchar(c);
  109.     fclose(infile);
  110.     fflush(stdout);
  111.     return (OK);
  112. }
  113.  
  114. catvalid(pname, name)
  115. char *pname;
  116. char *name;
  117. {
  118.     if((infile=fopen(name, "rb"))==NULL) {
  119.         fprintf(stderr, "Can't open %s\n", name);
  120.         return ERROR;
  121.     }
  122.     strcpy(pname, name);
  123.     return ('q');
  124. }
  125.  
  126. /*
  127.     The following code is primarily from typesq.c and utr.c.  Typesq
  128. is a modification of USQ by Dick Greenlaw.  Those modifications (usq
  129. to typesq) were made by Bob Mathias, I am responsible for the butchery
  130. done to make it work with cat.
  131.  
  132. */
  133.  
  134. qsend(fname)
  135. char *fname;
  136. {
  137.     register i, c;
  138.     register char *p;
  139.     register int numnodes;            /* size of decoding tree */
  140.     char origname[PATHLEN];     /* Original file name without drive */
  141.  
  142.     init_cr(); init_huff();
  143.  
  144.     if(portgetw(infile) != RECOGNIZE) {    /* Process header */
  145.         rewind(infile);
  146.         return 'a';                     /* not squeezed after all */
  147.     }
  148.     portgetw(infile);            /* discard checksum */
  149.     p = origname;                /* Get original file name */
  150.     do {                    /* send it to array */
  151.         *p = getc(infile);
  152.     } while(*p++ != '\0');
  153.  
  154.     numnodes = portgetw(infile);
  155.     if(numnodes < 0 || numnodes >= NUMVALS) {
  156.         fprintf(stderr, "%s has invalid decode tree size\n", fname);
  157.         fclose(infile);
  158.         return ERROR;
  159.     }
  160.     /* Initialize for possible empty tree (SPEOF only) */
  161.     Dnode[0]._children[0] = -(SPEOF + 1);
  162.     Dnode[0]._children[1] = -(SPEOF + 1);
  163.  
  164.     for(i = 0; i < numnodes; ++i) { /* Get decoding tree from file */
  165.         Dnode[i]._children[0] = portgetw(infile);
  166.         Dnode[i]._children[1] = portgetw(infile);
  167.     }
  168.     /* Get translated output bytes and write file */
  169.     fprintf(stderr, "\n%s -> %s\n\n",fname,origname);
  170.     early_exit = 0;
  171.     while( ((c = getcr(infile)) != EOF) && (!early_exit) )
  172.         putchar(c);
  173.     fclose(infile);
  174.     fflush(stdout);
  175.     return OK;
  176. }
  177. /*** from utr.c - */
  178. /* initialize decoding functions */
  179.  
  180. init_cr()
  181. {
  182.     Repct = 0;
  183. }
  184.  
  185. init_huff()
  186. {
  187.     Bpos = 99;    /* force initial read */
  188. }
  189.  
  190. /* Get bytes with decoding - this decodes repetition,
  191.  * calls getuhuff to decode file stream into byte
  192.  * level code with only repetition encoding.
  193.  *
  194.  * The code is simple passing through of bytes except
  195.  * that DLE is encoded as DLE-zero and other values
  196.  * repeated more than twice are encoded as value-DLE-count.
  197.  */
  198.  
  199. int
  200. getcr()
  201. {
  202.     register c;
  203.  
  204.     if(Repct > 0) {
  205.         /* Expanding a repeated char */
  206.         --Repct;
  207.         return Value;
  208.     } else {
  209.         /* Nothing unusual */
  210.         if((c = getuhuff()) != DLE) {
  211.             /* It's not the special delimiter */
  212.             Value = c;
  213.             if(Value == EOF)
  214.                 Repct = LARGE;
  215.             return Value;
  216.         } else {
  217.             /* Special token */
  218.             if((Repct = getuhuff()) == 0)
  219.                 /* DLE, zero represents DLE */
  220.                 return DLE;
  221.             else {
  222.                 /* Begin expanding repetition */
  223.                 Repct -= 2;    /* 2nd time */
  224.                 return Value;
  225.             }
  226.         }
  227.     }
  228. }
  229. /* Decode file stream into a byte level code with only
  230.  * repetition encoding remaining.
  231.  */
  232.  
  233. int
  234. getuhuff()
  235. {
  236.     register i;
  237.     register bitval;
  238.  
  239.     /* Follow bit stream in tree to a leaf*/
  240.     i = 0;    /* Start at root of tree */
  241.     do {
  242.         if(++Bpos > 7) {
  243.             if((Curin = getc(infile)) == ERROR)
  244.                 return ERROR;
  245.             Bpos = 0;
  246.             /* move a level deeper in tree */
  247.             i = Dnode[i]._children[1 & Curin];
  248.         } else
  249.             i = Dnode[i]._children[1 & (Curin >>= 1)];
  250.     } while(i >= 0);
  251.  
  252.     /* Decode fake node index to original data value */
  253.     i = -(i + 1);
  254.     /* Decode special endfile token to normal EOF */
  255.     i = (i == SPEOF) ? EOF : i;
  256.     return i;
  257. }
  258. /*
  259.  * Machine independent getw which always gets bytes in the same order
  260.  *  as the CP/M version of SQ wrote them
  261.  */
  262. portgetw(f)
  263. FILE *f;
  264. {
  265.     register c;
  266.  
  267.     c = getc(f)&0377;
  268.     return c + (getc(f)<<8);
  269. }
  270.  
  271.  
  272.